using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;

namespace HyuFrameWork
{
    public class UIManager : MonoSingleton<UIManager>
    {
        public const int BaseCanvasOrder = 99;
        [BoxGroup("Status"), ShowInInspector, ReadOnly]
        internal List<UIPage> PageStack = new List<UIPage>();

        [BoxGroup("Status"), ShowInInspector]
        public UIPage CurrentPage => PageStack.LastOrDefault();

        public Canvas BaseCanvas => gameObject.GetOrAddComponent<Canvas>();
        
        private void Start()
        {
            var baseCanvas = BaseCanvas;
            if (baseCanvas != null) 
            {
                baseCanvas.sortingOrder = BaseCanvasOrder;
            }
        }

        public static void ResetDefault()
        {
            if (m_instance == null) return;
            var inst = m_instance;
            inst.transform.RemoveAllChildren();
            inst.PageStack.Clear();
        }

        public static T Create<T>() where T : UIPanel
        {
            var prefab = UILoader.Load<T>();

            var root = GetRoot<T>();
            var go = Instantiate(prefab, root);
            var panel = go.GetComponent<T>();
            return panel;
        }
        
        public static T Open<T>() where T : UIPanel
        {
            var prefab = UILoader.Load<T>();

            var root = GetRoot<T>();
            var go = Instantiate(prefab, root);
            var panel = go.GetComponent<T>();
            panel.Open();

            return panel;
        }
        
        public static T Get<T>()
            where T : UIPanel
        {
            return Instance.GetComponentInChildren<T>(true);
        }

        public static T GetOrCreate<T>() where T : UIPanel
        {
            var panel = Get<T>();
            if (panel) return panel;

            return Create<T>();
        }
        
        public static T GetOrOpen<T>() where T : UIPanel
        {
            var panel = Get<T>();
            if (panel) return panel;

            return Open<T>();
        }
        
        public static T Close<T>() where T : UIPanel
        {
            var ui = Get<T>();
            if (ui != null)
            {
                ui.Close();
            }

            return ui;
        }
        
        public static T[] GetList<T>()
            where T : UIPanel
        {
            return Instance.GetComponentsInChildren<T>(true);
        }
        
        public static Transform GetRoot<T>() where T : UIPanel
        {
            if (typeof(T).IsSubclassOf(typeof(UIPageChild)))
            {
                if (Instance.CurrentPage)
                {
                    return Instance.CurrentPage.transform;
                }
            }

            return Instance.transform;
        }
    }
}